<head>
    <title>神奇弹幕投票</title>
    <script src="../js/jquery.js"></script>
    <script src="../js/vue.js"></script>
    <script src="../js/mdui.js"></script>
    <link rel="stylesheet" href="vote.css" />
    <link rel="stylesheet" href="vote_custom.css" />
    <link rel="stylesheet" href="../css/mdui.css" />
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<body>
    <div id="vote-container">
        <div contenteditable="true" class="editable-div title-edit">{{title}}</div>
        <div contenteditable="true" class="editable-div sub-title-edit">{{subTitle}}</div>

        <div class="mdui-divider"></div>

        <table class="vote-box-list" id="voteBox">
            <tr is="vote-item" v-for="(item, index) in voteItems" v-bind:key="item.id" v-bind:id="item.id"
                v-bind:uniqueid="item.uniqueid" v-bind:menutarget="item.menutarget" v-bind:name="item.name"
                v-bind:votes="item.votes" v-bind:percentage="item.percentage" v-bind:bgcolor="item.bgcolor"
                v-on:inc1="changeVote(index, 1)" v-on:dec1="changeVote(index, -1)" v-on:remove="removeItem(index)"
                v-on:showlist="showList(index)">
            </tr>
        </table>

        <div id="newVoteList" style="white-space: nowrap; overflow-x: scroll;">
        </div>

        <form v-on:submit.prevent="addNewItem">
            <div class="mdui-textfield">
                <input class="mdui-textfield-input" style="display: inline;" type="text" v-model="newItemText"
                    id="new-item" placeholder="新的投票项名称" />
            </div>
        </form>

        <div id="votedList">
        </div>

    </div>

    <script type="text/javascript">
        var randColors = ["#5dbc5b", "#6c81b6", "#9eb5f0", "#a5cbd6", "#aee7f8", "#c2f263", "#d843b3", "#d8e929", "#e58652", "#e7ab6d", "#ee335f", "#fbe096", "#ffc535"];

        function getRandomColor() {
            var index = Math.floor(Math.random() * randColors.length);
            randColors.slice(index, 1);
            return randColors[index];
        }

        function releaseRandomColor(color) {
            randColors.push(color);
        }

        /* 投票每一项的组件 */
        Vue.component('vote-item', {
            template: '<tr class="vl-item">\
                                <td><h4 class="vote-item-id">{{id}}</h4></td>\
                                <td><div contentEditable="true" class="vote-item-name editable-div" onKeyDown={this.handleKeyDown}>{{name}}</div></td>\
                                <td><div class="vote-item-wrap">\
                                        <p class="vote-item-bar-bg">\
                                            <span class="vote-item-bar-fg mdui-ripple" :style="{background: bgcolor}" v-on:click="$emit(\'showlist\')""></span>\
                                        </p>\
                                    </div>\
                                </td>\
                                <td><button class="mdui-btn mdui-color-theme-accent vote-item-num" :mdui-menu="menutarget">{{votes}} ({{percentage}}%)</button>\
                                <ul class="mdui-menu" :id="uniqueid">\
                                    <li class="mdui-menu-item">\
                                        <a href="javascript:;" class="mdui-ripple" v-on:click="$emit(\'inc1\')">\
                                            <i class="mdui-menu-item-icon mdui-icon material-icons">exposure_plus_1</i>投票+1\
                                        </a>\
                                    </li>\
                                    <li class="mdui-menu-item">\
                                        <a href="javascript:;" class="mdui-ripple" v-on:click="$emit(\'dec1\')">\
                                            <i class="mdui-menu-item-icon mdui-icon material-icons">exposure_neg_1</i>投票-1\
                                        </a>\
                                    </li>\
                                    <li class="mdui-divider"></li>\
                                    <li class="mdui-menu-item">\
                                        <a href="javascript:;" class="mdui-ripple" v-on:click="$emit(\'remove\')">\
                                            <i class="mdui-menu-item-icon mdui-icon material-icons">delete_forever</i>删除\
                                        </a>\
                                    </li>\
                                </ul></td>\
                        </tr>',
            props: ['uniqueid', 'id', 'name', 'votes', 'percentage', 'bgcolor', 'menutarget']
        });

        let userVotes = new Map(); // 这个是存谁投过票了
        var votedUsers = []; // 这个是投票的有哪些用户（按顺序排序）

        votedUsers.push([]);
        votedUsers.push([]);

        // 新投票的用户
        function appendNewVote(uid, uname) {
            // 设置最多几个元素
            const maxCount = 5;
            if ($("#newVoteList").children().length >= maxCount) {
                $("#newVoteList").children().last().remove();
            }

            // 插入到开头
            $("#newVoteList").prepend('<a class="mdui-chip" style="margin: 10px;" href="https://space.bilibili.com/' + uid + '" target="_blank">\
                                    <img class="mdui-chip-icon" src="http://__DOMAIN__:__PORT__/api/header?uid='+ uid + '" />\
                                    <span class="mdui-chip-title">'+ uname + '</span>\
                                </a>');
        }

        // 将投票的用户名字显示出来
        function appendVotedUser(uid, uname) {
            $("#votedList").append('<a class="mdui-chip" style="margin: 10px;" href="https://space.bilibili.com/' + uid + '" target="_blank">\
                                    <img class="mdui-chip-icon" src="http://__DOMAIN__:__PORT__/api/header?uid='+ uid + '" />\
                                    <span class="mdui-chip-title">'+ uname + '</span>\
                                </a>');
        }

        var vm = new Vue({
            el: '#vote-container',
            data: {
                title: '神奇弹幕投票',
                subTitle: "发送弹幕“投票 id”即可参与投票~",
                newItemText: '',
                totalVotes: 0, // 总的票数
                totalWidth: 200,
                voteItems: [{
                    uniqueid: 'uni1',
                    menutarget: "{target: '#uni1'}",
                    id: 1,
                    name: '赞同',
                    votes: 0,
                    percentage: 0,
                    bgcolor: getRandomColor(),
                }, {
                    uniqueid: 'uni2',
                    menutarget: "{target: '#uni2'}",
                    id: 2,
                    name: '不赞同',
                    votes: 0,
                    percentage: 0,
                    bgcolor: getRandomColor(),
                }],
                nextItemId: 3,
                nextUniqueId: 3,
                currentVotedUserList: -1,
            },
            methods: {
                // 添加一个新的item
                addNewItem: function () {
                    this.voteItems.push({
                        uniqueid: 'uni' + this.nextUniqueId,
                        menutarget: "{target: '#uni" + this.nextUniqueId + "'}",
                        id: this.nextItemId++,
                        name: this.newItemText,
                        votes: 0,
                        percentage: 0,
                        bgcolor: getRandomColor(),
                    })
                    this.newItemText = '';
                    this.nextUniqueId++;
                    votedUsers.push([]);
                },
                removeItem: function (index) {
                    releaseRandomColor(this.voteItems[index].bgcolor);
                    this.voteItems.splice(index, 1);

                    // 修改投票索引与比例
                    this.voteItems.forEach(function (item, index) {
                        item.id = index + 1;
                    });
                    this.recalculatePercent();
                    this.nextItemId--;

                    // 修改或者取消用户记录
                    for (let uv of userVotes.entries()) {
                        console.log(uv);
                        var ind = uv[1] - 1;
                        if (ind == index) { // 移除了
                            userVotes.delete(uv[0]);
                        } else if (ind > index) { // 后面的，-1
                            userVotes.set(uv[0], ind - 1 + 1); // +1是因为ID和index的差
                        }
                    }
                    votedUsers.slice(index, 1);
                    // console.log(userVotes);
                    // console.log(votedUsers);

                    // 修改显示
                    if (this.currentVotedUserList == index) {
                        this.currentVotedUserList = -1;
                    } else if (this.currentVotedUserList > index) {
                        this.currentVotedUserList--;
                    }
                },
                // 进行投票或者取消投票操作
                changeVote: function (index, count) {
                    if (this.voteItems[index].votes + count >= 0) {
                        this.voteItems[index].votes += count;
                    } else {
                        this.voteItems[index].votes = 0;
                    }
                    this.recalculatePercent();
                },
                // 重新计算所有的比例
                recalculatePercent: function () {
                    var total = 0;
                    var width = this.totalWidth;
                    this.voteItems.forEach(function (item) {
                        total += item.votes;
                    });
                    this.totalVotes = total;

                    var spans = $(".vote-item-bar-fg");
                    this.voteItems.forEach(function (item, index) {
                        item.percentage = total == 0 ? 0 : Math.round(item.votes * 100 / total);
                        var w = total == 0 ? 0 : item.votes * width / total;
                        // $(spans[index]).width(w);
                        $(spans[index]).animate({
                            width: w + "px"
                        }, 'slow');
                    });
                },
                // 显示该投票的用户
                showList: function (index) {
                    $("#votedList").empty();
                    var list = votedUsers[index];
                    this.currentVotedUserList = index;
                    for (var i = 0; i < list.length; i++) {
                        var uid = list[i].uid;
                        var uname = list[i].uname;
                        appendVotedUser(uid, uname);
                    }
                },
            }
        });

        // Socket通讯
        $(document).ready(function () {
            var ws = new WebSocket("ws://__DOMAIN__:__WS_PORT__");
            ws.onopen = function () {
                ws.send('{"cmd": "cmds", "data": ["VOTE"]}');
            };
            ws.onmessage = function (e) {
                console.log(e.data);
                var json = JSON.parse(e.data);
                var cmd = json['cmd'];
                switch (cmd) {
                    case 'VOTE':
                        var id = json['id'];
                        var uid = json['uid'];
                        var uname = json['uname'];
                        if (userVotes.has(uid)) { // 已经投票过了
                            console.log("已投过票");
                            ws.send('{"cmd": "send_msg", "data": "您已投过票"}');
                            return;
                        }
                        if (id < 1 || id > vm.voteItems.length) { // 超过下标
                            console.log("无效的投票ID：${id}");
                            ws.send('{"cmd": "send_msg", "data": "无效的投票ID：' + id + '"}');
                            return;
                        }
                        var index = id - 1; ''
                        vm.changeVote(index, 1); // 投票操作
                        userVotes.set(uid, id); // 标记为已投过票
                        votedUsers[index].push({ "uid": uid, "uname": uname });
                        if (vm.currentVotedUserList == index) {
                            appendVotedUser(uid, uname);
                        }
                        appendNewVote(uid, uname);
                        // appendVotedUser(uid, uname, id); // 显示出来
                        break;
                    case 'CANCEL':
                        break;
                }
            };
        });
    </script>
</body>